/*
* Copyright (c) 2022，公司名称
* All rights reserved.
* 文件名称：low_side.c
* 摘要：低边MCU处理
* 当前版本：V1.0.0,WCD,2023/1/10,初版
* 历史版本：Vx.x.x，编写者/修改者，修改时间，修改内容（重大发布时，总结重点变更内容）
*/
#include "low_includes.h"


#define TEMP_FILTER_TIME (20)

#define TEMP_FILTER_LEN (20)

#define TIME_1S (1000u)
#define TIME_1MS (1u)

#define TEMP_80 (120U)
#define TEMP_90 (130U)
/*50 = 90*/
//#define TEMP_80 (90)
/*60 = 100*/
//#define TEMP_90 (100)

#define TEMP_105 (145U)
#define TEMP_110 (150U)
/*50*/
//#define TEMP_110 (90)
#define TEMP_115 (155U)
#define TEMP_120 (160U)
#define TEMP_125 (165U)
/*60*/
//#define TEMP_125 (100)
#define TEMP_149 (189U)

#define VBAT_8V (1638u)
#define VBAT_9V (1843u)
/*16v*/
//#define VBAT_16V (3276u)
/*15.5v*/
#define VBAT_16V (3174u)
/*17V*/
//#define VBAT_17V (3481u)
/*16.2v*/
#define VBAT_17V (3317u)

static uint16_t out_temp_filter[TEMP_FILTER_LEN] = {0};
static uint16_t in_temp_filter[TEMP_FILTER_LEN] = {0};
low_side_status low_side_st;
uint8_t uart_rx_buff = 0;

low_side_status low_side_st;
/*
 * 函数介绍: 低边数据初始化
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void low_data_init(void)
{
    memset(&low_side_st, 0u, sizeof(low_side_status));
    lin_msg_init();
}
/*
 * 函数介绍: 冒泡排序
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void Bubble_sort(uint16_t arr[], uint8_t size)
{
    uint8_t j = 0u;
    uint8_t i = 0;
    uint16_t tem = 0u;

    for (i = 0; i < size - 1; i++)//size-1是因为不用与自己比较，所以比的数就少一个
    {
        uint8_t count = 0;
        for (j = 0; j < size - 1 - i; j++)    //size-1-i是因为每一趟就会少一个数比较
        {
            if (arr[j] > arr[j + 1])//这是升序排法，前一个数和后一个数比较，如果前数大则与后一个数换位置
            {
                tem = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tem;
                count = 1;
            }
            else
            { ;
            }
        }
        if (count == 0)
        {            //如果某一趟没有交换位置，则说明已经排好序，直接退出循环
            break;
        }
        else
        { ;
        }
    }
}
/*
 * 函数介绍: 对输出温度进行滤波处理
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_temp_filter(void)
{
    static uint32_t tick = 0u;
    static uint8_t count = 0u;
    if (0 == tick)
    {
        tick = Get1MsTickVal();
    }
    else
    { ;
    }

    if ( 1 == Get1MsTickInterval(tick,TEMP_FILTER_TIME))
    {
        uint8_t result_index = (TEMP_FILTER_LEN >> 1) - 1;
        tick = Get1MsTickVal();
        out_temp_filter[count] = low_ADC_OrgiData.sensor1_out.avg;
        in_temp_filter[count] = low_ADC_OrgiData.sensor2_in.avg;
        count++;
        if (count == TEMP_FILTER_LEN)
        {
            count = 0;
            Bubble_sort(out_temp_filter, TEMP_FILTER_LEN);
            Bubble_sort(in_temp_filter, TEMP_FILTER_LEN);

//            low_side_st.Temp1_out = ntc_get_temp(NTC_TEMP, low_ADC_OrgiData.sensor1_out.avg);
            low_side_st.Temp1_out = ntc_get_temp(NTC_TEMP, out_temp_filter[result_index]);
        }
        else
        { ;
        }
    }
    else
    { ;
    }
}
/*
 * 函数介绍: ADC转换函数
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_ADC_convert(void)
{
    low_side_st.VBat = low_ADC_OrgiData.Vbat.avg;
//    low_temp_filter();
    low_side_st.Temp1_out = ntc_get_temp(NTC_TEMP, low_ADC_OrgiData.sensor1_out.avg);
    low_side_st.Temp2_in = ntc_get_temp(NTC_TEMP, low_ADC_OrgiData.sensor2_in.avg);
//    low_side_st.PCB_temp = ntc_get_temp(NTC_PCB, low_ADC_OrgiData.PCB_temp.avg) + 0.5;
    low_side_st.PCB_temp = low_uart_rx_st.sig.pcb_temp;
}
/*
 * 函数介绍: 处理互锁状态
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_lock_status(void)
{
    if (GET_LOCK_PORT_LEVEL())
    {
        /*已互锁*/
        low_side_st.lock = FALSE;
    }
    else
    {
        low_side_st.lock = TRUE;
    }
}
/*
 * 函数介绍: PCB温度超过120°
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_pcb_over_120(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = low_side_st.PCB_temp;

    if (temp >= TEMP_120 && temp <= TEMP_149 && FALSE == low_side_st.pcb_over_120)
    {
        if (1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.pcb_over_120 = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.pcb_over_120)
    {
        if (temp <= TEMP_115)
        {
            if (1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S))
            {
                low_side_st.pcb_over_120 = FALSE;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: PCB温度超过125°
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_pcb_over_125(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = low_side_st.PCB_temp;

    if (temp >= TEMP_125 && temp <= TEMP_149 && FALSE == low_side_st.pcb_over_125)
    {
        if ( 1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S) )
        {
            low_side_st.pcb_over_125 = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.pcb_over_125)
    {
        if (temp <= TEMP_110)
        {
            if ( 1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S) )
            {
                low_side_st.pcb_over_125 = FALSE;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: Vbat电压高
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_12V_high(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint16_t temp = low_side_st.VBat;

    if (0u == set_Tick_cnt)
    {
        set_Tick_cnt = Get1MsTickVal();
    }
    else
    { ;
    }

    if (0u == cancel_Tick_cnt)
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
    else
    { ;
    }

    if (temp >= VBAT_17V && FALSE == low_side_st.VBat_over)
    {
        if (1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.VBat_over = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.VBat_over)
    {
        if (temp <= VBAT_16V)
        {
            if (1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S) )
            {
                low_side_st.VBat_over = FALSE;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: Vbat电压低
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_12V_low(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint16_t temp = low_side_st.VBat;

    if (temp < VBAT_8V && FALSE == low_side_st.VBat_low)
    {
        if (1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.VBat_low = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.VBat_low)
    {
        if (temp >= VBAT_9V)
        {
            if (1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S))
            {
                low_side_st.VBat_low = FALSE;
            }
            else
            {
                NOP;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: 水温过温检测
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_over_temp(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = low_side_st.Temp1_out;

    if (temp >= TEMP_90 && temp <= TEMP_149 && (FALSE == low_side_st.over_temp) && FALSE == low_side_st.hot_temp)
    {
        if (1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.over_temp = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.over_temp)
    {
        if (temp <= TEMP_80)
        {
            if (1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S))
            {
                low_side_st.over_temp = FALSE;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: 水温过热检测
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_hot_temp(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = low_side_st.Temp1_out;

    if (temp >= TEMP_105 &&  temp <= TEMP_149 && FALSE == low_side_st.hot_temp)
    {
        if ( 1 == Get1MsTickInterval(set_Tick_cnt,TIME_1MS))
        {
            low_side_st.hot_temp = TRUE;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (TRUE == low_side_st.hot_temp)
    {
        if (temp <= TEMP_80)
        {
            if ( 1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S))
            {
                low_side_st.hot_temp = FALSE;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: 水温NTC开路
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_water_ntc_open(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = (low_ADC_OrgiData.sensor1_out.max >= NTC_OPEN) ||
                   (low_ADC_OrgiData.sensor2_in.max >= NTC_OPEN);

    uint8_t temp_cansel = (low_ADC_OrgiData.sensor1_out.max < NTC_OPEN) &&
                   (low_ADC_OrgiData.sensor2_in.max < NTC_OPEN);

    if (temp && ADC_VALUE_OPEN != low_side_st.ntc_status)
    {
        if ( 1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.ntc_status = ADC_VALUE_OPEN;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (ADC_VALUE_OPEN == low_side_st.ntc_status)
    {
        if (temp_cansel)
        {
            if ( 1 == Get1MsTickInterval(cancel_Tick_cnt,TIME_1S) )
            {
                low_side_st.ntc_status = ADC_VALUE_VALID;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: 水温NTC短路
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_water_ntc_short(void)
{
    static uint32_t set_Tick_cnt = 0u;
    static uint32_t cancel_Tick_cnt = 0u;
    uint8_t temp = (low_ADC_OrgiData.sensor1_out.min <= NTC_SHORT) ||
                   (low_ADC_OrgiData.sensor2_in.min <= NTC_SHORT);

    uint8_t temp_cansel = (low_ADC_OrgiData.sensor1_out.min > NTC_SHORT) &&
                   (low_ADC_OrgiData.sensor2_in.min > NTC_SHORT);

    if (temp && ADC_VALUE_SHORT != low_side_st.ntc_status)
    {
        if ( 1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
        {
            low_side_st.ntc_status = ADC_VALUE_SHORT;
        }
        else
        { ;
        }
    }
    else
    {
        set_Tick_cnt = Get1MsTickVal();
    }

    if (ADC_VALUE_SHORT == low_side_st.ntc_status)
    {
        if (temp_cansel)
        {
            if ( 1 == Get1MsTickInterval(set_Tick_cnt,TIME_1S))
            {
                low_side_st.ntc_status = ADC_VALUE_VALID;
            }
            else
            { ;
            }
        }
        else
        {
            cancel_Tick_cnt = Get1MsTickVal();
        }
    }
    else
    {
        cancel_Tick_cnt = Get1MsTickVal();
    }
}
/*
 * 函数介绍: 低边错误检测
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_error_check(void)
{
    low_lock_status();
    low_pcb_over_120();
    low_pcb_over_125();
    low_12V_high();
    low_12V_low();
#if 1
    low_over_temp();
    low_hot_temp();
    low_water_ntc_open();
    low_water_ntc_short();
#endif
}
static ptc_error_en low_side_set_ptc_error(void)
{
   ptc_error_en res =  PTC_ERROR_NONE;

   if (low_side_st.over_temp)
   {
       res = PTC_ERROR_OVER_TEMP;
   }
   else if(low_side_st.lock)
    {
        res = PTC_ERROR_LOCK;
    }
   else if (low_side_st.hot_temp )
   {
       res = PTC_ERROR_HOT_TEMP;
   }
   else if (low_side_st.pcb_over_120 )
   {
       res = PTC_ERROR_PCB_OVER_120;
   }
   else if (low_side_st.pcb_over_125 )
   {
       res = PTC_ERROR_PCB_OVER_125;
   }
   else if (low_side_st.VBat_over)
   {
       res = PTC_ERROR_12V_HIGH;
   }
   else if (low_side_st.VBat_low )
   {
       res = PTC_ERROR_12V_LOW;
   }
   else if (ADC_VALUE_OPEN == low_side_st.ntc_status )
   {
       res = PTC_ERROR_NTC_OPEN;
   }
   else if (ADC_VALUE_SHORT == low_side_st.ntc_status )
   {
       res = PTC_ERROR_NTC_SHORT;
   }
   else if (TRUE == low_side_st.lin_mode_invalid)
   {
       res = PTC_ERROR_LIN_MODE_INVALID;
   }
   else
   {;}
    return res;
}
/*
 * 函数介绍: 通过串口发送数据到高边
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_set_uart_to_high_data(void)
{
    if (low_uart_tx_st.sig.mode != PTC_MODE_INVALID )
    {
        low_uart_tx_st.sig.ptc_off_on = CA_Contrl.msg.sig.HVH_ON_OFF;
    }
    else
    {
//        low_side_st.lin_mode_invalid = TRUE;
        low_uart_tx_st.sig.ptc_off_on = HVH_MODE_OFF;
    }

    low_uart_tx_st.sig.ptc_error_status = low_side_set_ptc_error();
    if (FALSE  == low_side_st.pcb_over_120 )
    {
        low_uart_tx_st.sig.pwm_percent = CA_Contrl.msg.sig.HVH_power_ratio >> 1;
    }
    else
    {
        low_uart_tx_st.sig.pwm_percent = CA_Contrl.msg.sig.HVH_power_ratio;
    }
    low_uart_tx_st.sig.set_temp = CA_Contrl.msg.sig.Temp_set + NTC_OFFSET;
    low_uart_tx_st.sig.act_temp = low_side_st.Temp1_out;
    low_uart_tx_st.sig.act_temp_deci =
            (low_side_st.Temp1_out - low_uart_tx_st.sig.act_temp) * 10;
    low_uart_tx_st.sig.in_temp = low_side_st.Temp2_in;
}
void low_IGBT_handle(void)
{
#if 1
//    low_side_st.ntc_status == ADC_VALUE_VALID &&
//    CA_Contrl.msg.sig.HVH_ON_OFF = HVH_MODE_POWER;


    if (low_uart_rx_st.sig.ptc_all_error_status == PTC_HIGH_IGBT_SHORT)
    {
        IGBT_PORT_OFF();
        low_uart_tx_st.sig.mode = PTC_MODE_INVALID;
    }
    else if (!low_side_st.VBat_low &&
        !low_side_st.VBat_over && !low_side_st.lock && !low_side_st.over_temp &&
        !low_side_st.hot_temp &&
        !low_side_st.pcb_over_125 && low_side_st.ntc_status == ADC_VALUE_VALID)
    {
        IGBT_PORT_ON();
        low_uart_tx_st.sig.mode = PTC_MODE_TEMP;
    }
    else
    {
        IGBT_PORT_OFF();
        low_uart_tx_st.sig.mode = PTC_MODE_INVALID;
    }
#else
    low_uart_tx_st.sig.mode = PTC_MODE_TEMP;
#endif
}
/*
 * 函数介绍: HVH DEG错误
 * 参数:
 * 返回值: {*}
 * 备注: 1) PCB 温度范围
        2) 高压电压限制
        3) 高压电流范围
 */
static void low_run_status_HVH_DEG(void)
{
    if (low_side_st.pcb_over_120 || low_side_st.pcb_over_125 ||
        low_uart_rx_st.sig.HV_voltage_st != VOLTAGE_VALID || low_uart_rx_st.sig.cur_over30)
    {
        if (Report_Value.msg.sig.HVH_RunStatus != HVH_DEG)
        {
            Report_Value.msg.sig.HVH_RunStatus = HVH_DEG;
        }
        else
        { ;
        }
    }
    else if (HVH_DEG == Report_Value.msg.sig.HVH_RunStatus)
    {
        Report_Value.msg.sig.HVH_RunStatus = HVH_ON;
    }
}

/*
 * 函数介绍:发送停止命令
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_run_status_HVH_stop(void)
{
    if (low_side_st.VBat_low || low_side_st.VBat_over)
    {
        Report_Value.msg.sig.HVH_RunStatus = HVH_STOP;
    }
    else
    { ;
    }
}

/*
 * 函数介绍: 通过LIN发送short指令
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_run_status_short(void)
{
    if (IGBT_ST_SHORT == low_uart_rx_st.sig.IGBT_status)
    {
        Report_Value.msg.sig.HVH_RunStatus = HVH_SHORTED;
    }
    else
    { ;
    }
}

/*
 * 函数介绍:通过LIN发送shutdown指令
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_run_status_shutdown(void)
{
    if (low_side_st.ntc_status != ADC_VALUE_VALID)
    {
        Report_Value.msg.sig.HVH_RunStatus = HVH_SHUTDOWN;
    }
    else
    { ;
    }
}

static void low_run_status(void)
{
    low_run_status_HVH_DEG();
    low_run_status_HVH_stop();
    low_run_status_shutdown();
    low_run_status_short();
}
/*
 * 函数介绍:准备LIN发送的数据
 * 参数:
 * 返回值: {*}
 * 备注:
 */
static void low_lin_send_data(void)
{
#if 0
    Report_Value.msg.sig.HVH_CurrSens_Flt =
#else
    Report_Value.msg.sig.RsErr_HVH = NO_ERR_DETECTED;
    Report_Value.msg.sig.Temp_of_InWater = low_side_st.Temp2_in;
    Report_Value.msg.sig.Tempe_of_OutWater = low_side_st.Temp1_out;
    Report_Value.msg.sig.HVH_HeaterCircuits = low_uart_rx_st.sig.IGBT_error_num;
    Report_Value.msg.sig.HVH_HV_Voltage_Valid = low_uart_rx_st.sig.HV_voltage_st;
    Report_Value.msg.sig.HVH_TempSens_Flt = NO_FAULT;
    Report_Value.msg.sig.HVH_Sp_LIN_Flt = NO_TIMEOUT;
    Report_Value.msg.sig.HVH_Off_ShrtCurr = low_uart_rx_st.sig.cur_short;
    if (low_uart_rx_st.sig.ptc_all_error_status != PTC_ERROR_NONE)
    {
        Report_Value.msg.sig.power = low_uart_rx_st.sig.ptc_all_error_status;
    }
    else
    {
        Report_Value.msg.sig.power = low_uart_rx_st.sig.power;
    }

    Report_Value.msg.sig.HVH_HV_Voltage = low_uart_rx_st.sig.hv_voltage;
    Report_Value.msg.sig.HVH_InternalPCBTemp = low_side_st.PCB_temp;

    low_run_status();

    if (low_side_st.VBat_low == TRUE || low_side_st.VBat_over == TRUE)
    {
        Report_Value.msg.sig.HVH_Sp_ExtPwrSup_Flt = OUT_OF_RANGE;
    }
    else
    {
        Report_Value.msg.sig.HVH_Sp_ExtPwrSup_Flt = IN_THE_RANGE;
    }

    if (low_side_st.over_temp == TRUE || low_side_st.hot_temp == TRUE)
    {
        Report_Value.msg.sig.HVH_TempLim = OVERTEMP;
    }
    else
    {
        Report_Value.msg.sig.HVH_TempLim = NO_OVERTEMP;
    }

#endif
}
/*
 * 函数介绍: 低边处理
 * 参数:
 * 返回值: {*}
 * 备注:
 */
void low_handle(void)
{
    low_ADC_convert();
    //low_uart31_tx();//不适用
    low_error_check();
    low_set_uart_to_high_data();
    low_IGBT_handle();
    low_uart30_rx_tx_handle();
    low_lin_send_data();
}